package com.rds.common.utils;

import com.rds.common.constant.HttpStatus;
import com.rds.common.exception.CustomException;
import com.rds.common.mail.EmailBean;
import com.rds.common.mail.EmailUser;
import com.rds.common.mail.MailConfig;
import com.sun.mail.util.MailSSLSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;

@Component
public class EmailUtil {
    private static final Logger log = LoggerFactory.getLogger(EmailUtil.class);
    @Autowired
    private MailConfig mailConfig;
    /**
     * @Title: sendMail
     * @Description:开始发送邮件
     * @param recipientType_TO (必填) 收件人，可以配置多个
     * @param recipientType_CC (可选) 抄送人，可以配置多个
     * @param recipientType_BCC(可选) 密送人，可以配置多个,其他人无法知道密送人收到邮件
     * @param emailTitle 邮件主题
     * @param emailContent 邮件内容
     * @param annexPaths 附件路径
     * @author weny.yang
     * @update : LiChuanlong
     * @updateContent : 通过注解获取配置信息
     * @updateDate: 2022/05/31 12:12
     */
    public void sendMail(List<EmailUser> recipientType_TO, List<EmailUser> recipientType_CC, List<EmailUser> recipientType_BCC, String emailTitle, StringBuffer emailContent, List<String> annexPaths) throws Exception{
        String host = mailConfig.getHost();//邮件服务器
        String protocol = mailConfig.getProtocol();//邮件发送协议
        //String port = mailConfig.getPort(); //发件邮件端口
        String auth = mailConfig.getAuth();//需要验证用户名密码
        String enable = mailConfig.getEnable();//ssl加密
        String name = mailConfig.getName();//发件人名称
        String address = mailConfig.getFromAddress();//发件人邮件地址
        String password = mailConfig.getPassword();//发件人授权码
        String emailType = mailConfig.getEmailType();//是否开启邮箱发送

        System.out.println("emailType = " + emailType);
        if("true".equals(emailType)){
            //设置发送者邮箱相关信息
            if(StringUtils.isNotBlank(address)){
                EmailUser emailUser = new EmailUser(name,address,password);
                EmailBean bean = new EmailBean(host,emailUser,recipientType_TO,recipientType_CC,recipientType_BCC,emailTitle,emailContent.toString(),annexPaths);
                //发送邮件
                sendEmail(bean,protocol,auth,enable);
            }
        }else{
            //throw new Exception("邮箱配置属于关闭状态，发送邮箱失败");
            throw new CustomException("邮箱配置属于关闭状态,发送邮箱失败", HttpStatus.NOT_MODIFIED);
        }
    }
    public static  void sendEmail(EmailBean bean,String protocol,String auth,String enable) throws  Exception{
        sendEmail(bean,"",protocol,auth,enable);
    }
    /**
     * @Title: sendEmail
     * @Description:发送复杂邮件
     * @author weny.yang
     */
    public static void sendEmail(EmailBean bean,String port,String protocol,String auth,String enable) throws  Exception{
        Transport transport = null;
        try {
            log.info("发送邮件开始[" + bean.getEmailTitle() + "]");
            //System.out.println("邮件原始信息bean = " + bean);
            Properties prop = new Properties();
            prop.setProperty("mail.smtp.auth", "true");// 指定是否需要SMTP验证
            prop.setProperty("mail.smtp.host", bean.getSmtpHost());// 指定SMTP服务器
            prop.put("mail.transport.protocol", "smtp");
            Session session = Session.getDefaultInstance(prop);
            session.setDebug(false);// 是否在控制台显示debug信息

            /*prop.setProperty("mail.smtp.host", bean.getSmtpHost());// 指定SMTP服务器
            //prop.setProperty("mail.host", bean.getSmtpHost()); // 邮件服务器
            //prop.setProperty("mail.smtp.port", port);//端口
            prop.setProperty("mail.transport.protocol", protocol); // 邮件发送协议
            prop.setProperty("mail.smtp.auth", auth); // 需要验证用户名密码
            // SSL加密
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            prop.put("mail.smtp.ssl.enable", enable);
            prop.put("mail.smtp.ssl.socketFactory", sf);
            // 1、创建应用程序所需的环境会话 session 对象
            Session session = Session.getDefaultInstance(prop, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    // 发件人的邮箱地址和密码
                    return new PasswordAuthentication(bean.getFromUser().getAddress(), bean.getFromUser().getPassword());
                }
            });*/
            // 2、获取 transport 对象
            transport = session.getTransport("smtp");
            // 3、连接邮箱服务器
            log.info("邮件发件者信息[101]-->Host:"+bean.getSmtpHost()+"\t:From:"+bean.getFromUser().getAddress()+"\t:Password:"+bean.getFromUser().getPassword());
            transport.connect(bean.getSmtpHost(), bean.getFromUser().getAddress(), bean.getFromUser().getPassword());
            // 4、创建复杂邮件
            MimeMessage mimeMessage = creatComplexEmail(session, bean);
            // 5、发送邮件
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
            log.info("发送邮件完成[" + bean.getEmailTitle() + "]");
        } catch (Exception e) {
            //e.printStackTrace();
            log.error("邮件发送异常", e);
            throw new CustomException("邮件发送失败",HttpStatus.ERROR);
        } finally {
            try {
                if (null != transport) {
                    // 6、关闭连接
                    transport.close();
                }
            } catch (MessagingException e) {
                log.error("资源释放异常", e);
                throw new CustomException("资源释放异常",HttpStatus.ERROR);
            }
        }
    }

    /**
     * @Title: complexEmail
     * @Description:创建复杂邮件
     * @author weny.yang
     */
    private static MimeMessage creatComplexEmail(Session session, EmailBean bean) throws Exception {
        // 消息信息
        MimeMessage message = new MimeMessage(session);

        // 发件人
        message.setFrom(new InternetAddress(bean.getFromUser().getAddress(), bean.getFromUser().getName(), "UTF-8"));
        // 收件人
        List<EmailUser> toList = bean.getRecipientType_TO();
        // 抄送人
        List<EmailUser> ccList = bean.getRecipientType_CC();
        // 密送人
        List<EmailUser> bccList = bean.getRecipientType_BCC();

        /**发送邮件给收件人**/
        if (toList != null) {
            message.setRecipients(MimeMessage.RecipientType.TO,covertEmailAddress(toList));
        }
        /**抄送邮件给收件人**/
        if (ccList != null) {
            message.setRecipients(MimeMessage.RecipientType.CC,covertEmailAddress(ccList));
        }
        /**密送邮件给收件人**/
        if (bccList != null) {
            message.setRecipients(MimeMessage.RecipientType.BCC,covertEmailAddress(bccList));
        }

        // 邮件标题
        message.setSubject(bean.getEmailTitle());
        // 邮件文本
        MimeBodyPart text = new MimeBodyPart();
        text.setContent(bean.getEmailContent(), "text/html;charset=utf-8");// 支持html标签解析，展示自定义格式
        // 组装邮件
        MimeMultipart allFile = new MimeMultipart();
        // 添加文本
        allFile.addBodyPart(text);
        // 添加附件
        List<String> annexPaths = bean.getAnnexPaths();
        if (annexPaths != null && annexPaths.size() > 0) {
            for (String path : annexPaths) {
                MimeBodyPart appendix = new MimeBodyPart();
                DataHandler dataHandler = new DataHandler(new FileDataSource(path));
                appendix.setDataHandler(dataHandler);
                appendix.setFileName(MimeUtility.encodeText(new File(path).getName()) );
                allFile.addBodyPart(appendix);//设置附件
            }
        }
        allFile.setSubType("mixed"); //正文和附件都存在邮件中，所有类型设置为mixed
        // 放到Message消息中
        message.setContent(allFile);
        // 显示的发件时间
        message.setSentDate(new Date());
        message.saveChanges();//保存修改
        return message;
    }

    /**
    * @description: 获取收件者/抄件者/密送者邮件信息
    * @param: 邮箱对象信息集合
    * @return: 邮件地址
    * @author: LiChuanlong
    * @date: 2022/5/31 14:39
    */
    private static Address[] covertEmailAddress(List<EmailUser> recipents) throws  Exception{
        Address[] address = new Address[recipents.size()];
        int index = 0;
        for(EmailUser user : recipents){
            address[index] = new InternetAddress(user.getAddress(),user.getName(),"UTF-8");
            index ++;
        }
        return address;

    }


    /**
     * 邮箱模板1
     *
     * @param taskName 任务名称
     * @param projectName 项目名称
     * @param userName 发起人信息
     * @param url url
     * @param urlName url名称
     * @return 用户对象信息
     */
    public StringBuffer MailTemplate(String taskName,String projectName,String userName,String url,String urlName){
        StringBuffer content=new StringBuffer();
        content.append("邮件通知内容：");
        content.append("<br>任务名称："+taskName);
        content.append("<br>项目名称："+projectName);
        content.append("<br>发起人："+userName);
        content.append("<br>链接：<a style='text-decoration: none;' href='"+url+"'>"+urlName+"</a></p>");
        return content;
    }


    /**
     * 邮箱模板2
     * @param taskName 任务名称
     * @param projectName 项目名称
     * @param finalTask 已为您分派的任务
     * @param startDate 开始时间
     * @param startDate2 到~时间
     * @param dueHours 持续时间（小时）
     * @param url url
     * @param urlName url名称
     * @return 用户对象信息
     */
    public static StringBuffer MailTemplate2(String taskName,String projectName,String finalTask,String startDate,String startDate2,String dueHours,String url,String urlName){
        StringBuffer content=new StringBuffer();
        if(taskName!=null && taskName.length()>0){
            taskName="\""+taskName+"\"";
        }
        if(projectName!=null && projectName.length()>0){
            projectName="\""+projectName+"\"";
        }
        if(finalTask!=null && finalTask.length()>0){
            finalTask="'"+finalTask+"'";
        }
        if(startDate!=null && startDate.length()>0){
            startDate="'"+startDate+"'";
        }
        if(startDate2!=null && startDate2.length()>0){
            startDate2="'"+startDate2+"'";
        }
        if(dueHours!=null && dueHours.length()>0){
            dueHours="'"+dueHours+"'";
        }
        content.append("请检查以下业务对象："+taskName+projectName+"已为你分派任务"+finalTask+"。于"+startDate+"开始，于"+startDate2+"到期,持续时间为"+dueHours+"。");
        content.append("<br><a style='text-decoration: none;' href='"+url+"'>"+urlName+"</a></p>");
        return content;
    }

    /**
     * 邮箱模板3
     *
     * @param workflowName 流程名称
     * @param title 标题
     * @param url url
     * @param urlName url名称
     * @return 用户对象信息
     */
    public StringBuffer MailTemplate3(String workflowName,String title,String url,String urlName){
        StringBuffer content=new StringBuffer();
        content.append("流程已审批完成");
        content.append("<br>名称："+workflowName);
        content.append("<br>标题："+title);
        content.append("<br>链接：<a style='text-decoration: none;' href='"+url+"'>"+urlName+"</a></p>");
        return content;
    }

    /**
     * 邮箱模板4
     * @param workflowName 流程名称
     * @param taskName 流程任务名称
     * @return 用户对象信息
     */
    public StringBuffer MailTemplate4(String workflowName,String taskName){
        StringBuffer content=new StringBuffer();
        content.append("你有一条新的待审批的流程任务,请登陆系统及时处理");
        content.append("<br>流程名称："+workflowName);
        content.append("<br>流程任务名称："+taskName);
        return content;
    }

    /**
     * 邮箱模板5
     * @param workflowName 流程名称
     * @param taskName 流程任务名称
     * @return 用户对象信息
     */
    public StringBuffer MailTemplate5(String workflowName,String taskName){
        StringBuffer content=new StringBuffer();
        content.append("你有驳回的流程任务，请检查后重新发起流程");
        content.append("<br>流程名称："+workflowName);
        content.append("<br>流程任务名称："+taskName);
        return content;
    }
}
